//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifndef __POBJENUM_H__
#define __POBJENUM_H__

#include <elasys_server.h>
#include <linknode.h>
#include <interlocked.h>

#define INVALID_ENUMERATOR_ID (-1)

typedef Int32 EnumeratorType;
enum {
    EnumeratorType_Process = 0,
    EnumeratorType_Thread  = 1,
    EnumeratorType_Module  = 2
};

class CPseudoObjectEnumerator: public IObjectEnumerator
{
public:
    CARAPI_(PInterface) Probe(
        /* [in] */ REIID riid);

    CARAPI_(UInt32) AddRef(void);

    CARAPI_(UInt32) Release(void);

    CARAPI Aggregate(
        /* [in] */ AggrType aggrType,
        /* [in] */ PInterface pObject);

    CARAPI GetDomain(
        /* [out] */ PInterface *ppObject);

    CARAPI Current(
        /* [out] */ PInterface *ppObject);

    CARAPI MoveNext(
        /* [out] */ Boolean *pSucceeded);

    CARAPI Reset();

private:
    Interlocked m_nRefs;
};

class CPseudoProcessEnumerator : public CPseudoObjectEnumerator
{
public:
    CARAPI Current(
        /* [out] */ PInterface *ppObject);

    CARAPI MoveNext(
        /* [out] */ Boolean *pSucceeded);

    CARAPI Reset();

public:
    CPseudoProcessEnumerator()
        : m_enumeratorId(INVALID_ENUMERATOR_ID) {}

    virtual ~CPseudoProcessEnumerator();
    ECode Initialize();

private:
    Int32 m_enumeratorId;

};

class CPseudoThreadEnumerator : public CPseudoObjectEnumerator
{
public:
    CARAPI Current(
        /* [out] */ PInterface *ppObject);

    CARAPI MoveNext(
        /* [out] */ Boolean *pSucceeded);

    CARAPI Reset();

public:
    CPseudoThreadEnumerator(ProcessId processId,
                        IProcess * pProcess)
                      : m_processId(processId),
                        m_pProcess(pProcess),
                        m_hLock(NULL),
                        m_pProxy(NULL) {}

    virtual ~CPseudoThreadEnumerator();
    ECode Initialize();

private:
    ProcessId      m_processId;
    IProcess     * m_pProcess;

    PVoid          m_hLock;
    IObjectEnumerator * m_pProxy;
};

class CPseudoModuleEnumerator : public CPseudoObjectEnumerator
{
public:
    CARAPI Current(
        /* [out] */ PInterface *ppObject);

    CARAPI MoveNext(
        /* [out] */ Boolean *pSucceeded);

    CARAPI Reset();

public:
    CPseudoModuleEnumerator(ProcessId processId,
                        IProcess * pProcess)
                      : m_processId(processId),
                        m_pProcess(pProcess),
                        m_hLock(NULL),
                        m_pProxy(NULL) {}

    virtual ~CPseudoModuleEnumerator();
    ECode Initialize();

private:
    ProcessId      m_processId;
    IProcess     * m_pProcess;

    PVoid          m_hLock;
    IObjectEnumerator * m_pProxy;
};

class CPseudoEnumeratorBuilder
{
public:
    ECode BuildForDummy(
        /* [out] */ IObjectEnumerator ** ppEnumerator);

    ECode BuildForProcess(
        /* [out] */ IObjectEnumerator ** ppEnumerator);

    ECode BuildForThread(
        /* [in] */ ProcessId processId,
        /* [in] */ IProcess * pProcess,
        /* [out] */ IObjectEnumerator ** ppEnumerator);

    ECode BuildForModule(
        /* [in] */ ProcessId processId,
        /* [in] */ IProcess * pProcess,
        /* [out] */ IObjectEnumerator ** ppEnumerator);
};

#endif //__POBJENUM_H__
